/*
 *
 *      Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the pig4cloud.com developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: lengleng (wangiegie@gmail.com)
 *
 */

package com.pig4cloud.pig.admin.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pig.admin.api.dto.UserDTO;
import com.pig4cloud.pig.admin.api.entity.SysLog;
import com.pig4cloud.pig.admin.api.entity.SysUser;
import com.pig4cloud.pig.admin.api.vo.PreLogVo;
import com.pig4cloud.pig.admin.service.SysLogService;
import com.pig4cloud.pig.admin.service.SysUserService;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.security.annotation.Inner;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 日志表 前端控制器
 * </p>
 *
 * @author lengleng
 * @since 2017-11-20
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping({"/log", "/cpsRole/log"})
@Api(value = "log", tags = "日志管理模块")
public class SysLogController {
	private final SysLogService sysLogService;
	private final SysUserService sysUserService;

	/**
	 * 简单分页查询
	 *
	 * @param page   分页对象
	 * @param sysLog 系统日志
	 * @return
	 */
	@GetMapping("/page")
	public R getLogPage(Page page, SysLog sysLog) {
		LambdaQueryWrapper<SysLog> query = new LambdaQueryWrapper<>();
		query.orderByDesc(SysLog::getCreateTime);
		query.and(StringUtils.isNotBlank(sysLog.getType()), wrapper -> wrapper.eq(SysLog::getType, sysLog.getType()));
		//不查询匿名用户
		query.and(wrapper -> wrapper.ne(SysLog::getCreateBy, "anonymousUser"));
		//暂支持单选  optType = "/user#put"
		if (StringUtils.isNotBlank(sysLog.getOptType())) {
			String[] opt = sysLog.getOptType().split("#");
			String uri = opt[0];
			if (uri.endsWith("*")) {
				query.and(wrapper -> wrapper.like(SysLog::getRequestUri, uri.substring(0, uri.length() - 1)));
			} else {
				query.and(wrapper -> wrapper.eq(SysLog::getRequestUri, uri));
			}
			query.and(wrapper -> wrapper.eq(SysLog::getMethod, opt[1].toUpperCase()));
		}
//		if (StringUtils.isNotBlank(sysLog.getOptType())) {
//			List<String> urls = new ArrayList<>(Arrays.asList(sysLog.getOptType().split(","))).stream().collect(Collectors.toList());
//			query.in(SysLog::getRequestUri,urls);
//		}
		if (StringUtils.isNotBlank(sysLog.getRealName())) {
			final List<String> usernames = sysUserService.list(Wrappers.<SysUser>lambdaQuery().select(SysUser::getUsername).like(SysUser::getRealName, sysLog.getRealName().trim())).stream().map(SysUser::getUsername).collect(Collectors.toList());
			if (usernames.isEmpty()) {
				return R.ok(new Page<>());
			} else {
				query.in(SysLog::getCreateBy, usernames);
			}
		}
		IPage<SysLog> sysLogList = sysLogService.page(page, query);
		//获取真实名称
		List<SysLog> list = sysLogList.getRecords();
		if (CollectionUtils.isNotEmpty(list)) {
			List<String> userNameList = list.stream().map(SysLog::getCreateBy).filter(Objects::nonNull).collect(Collectors.toList());
			List<SysUser> sysUserList = sysUserService.list(Wrappers.<SysUser>lambdaQuery().in(SysUser::getUsername, userNameList));
			list.forEach(item -> {
				//默认显示登录名
				item.setRealName(item.getCreateBy());
				if (CollectionUtils.isNotEmpty(sysUserList)) {
					sysUserList.forEach(user -> {
						if (user.getUsername().equals(item.getCreateBy())) {
							item.setRealName(user.getRealName());
						}
					});
				}
			});
		}
		return R.ok(sysLogList);
	}

	/**
	 * 删除日志
	 *
	 * @param id ID
	 * @return success/false
	 */
	@DeleteMapping("/{id}")
	@PreAuthorize("@pms.hasPermission('sys_log_del')")
	public R removeById(@PathVariable Long id) {
		return R.ok(sysLogService.removeById(id));
	}

	/**
	 * 插入日志
	 *
	 * @param sysLog 日志实体
	 * @return success/false
	 */
	@Inner
	@PostMapping("/save")
	public R save(@Valid @RequestBody SysLog sysLog) {
		// 更新用户最后操作时间 20210902 hejiale
		try {
			String createBy = sysLog.getCreateBy();
			if (StringUtils.isNotBlank(createBy)) {
				UserDTO userDto = new UserDTO();
				userDto.setUsername(createBy);
				userDto.setLastOperateTime(LocalDateTime.now());

				// 登录成功日志，更新最后登录时间
				if ("登录成功".equals(sysLog.getTitle())) {
					userDto.setLastLoginTime(LocalDateTime.now());
				}
				sysUserService.updateUserInfo(userDto);
			}
		} catch (Exception e) {
			log.error("更新用户最后操作时间异常", e);
		}
		return R.ok(sysLogService.save(sysLog));
	}

	/**
	 * 批量插入前端异常日志
	 *
	 * @param preLogVoList 日志实体
	 * @return success/false
	 */
	@PostMapping("/logs")
	public R saveBatchLogs(@RequestBody List<PreLogVo> preLogVoList) {
		return R.ok(sysLogService.saveBatchLogs(preLogVoList));
	}
}
